/**
 * 数据准备完毕后执行相关方法
 * 使用方法：
 * var dataReady = new DataReady();//创建对象
 *
 * dataReady.pushDataSource({//设置第一个数据源
 *  url : xxx,
 *  key : key1,
 *  success : function(){}
 *  error : function(){}
 * });
 *
 * dataReady.pushDataSource({//设置第二个数据源
 *  url : xxx,
 *  key : key2,
 *  success : function(){}
 *  error : function(){}
 * });
 *
 * dataReady.start()//启动。所有数据源执行完毕后，会逐个执行每个数据源的success、error、complete回调函数
 *
 * 或者
 *
 * dataReady.once(function(data){})//启动。所有数据源执行完毕后，执行一次给定的方法，方法的入参data = {
 *  key1 : {data : {} , isFail : boolean},//属性key1来源于设置第一个数据源时定义的key值
 *  key2 : {data : {} , isFail : boolean} //属性key2来源于设置第二个数据源时定义的key值
 * }
 *
 * Created by 杨浩宇 on 2016-01-13.
 */
define(['require' , 'jquery'], function (require , $) {
    function DataReady() {
        this._dataSource=[];
    }

    /**
     * 数据源
     * @type {Array}
     */
    DataReady.prototype._dataSource = [];

    DataReady.prototype.ajaxOptsDefault = {
        type: "get",
        contentType: "application/json",
        dataType: "json"
    };

    /**
     * 增加数据源
     *
     * @param opts ， jquery.ajax()方法的参数，必须设置一个唯一的key值
     */
    DataReady.prototype.pushDataSource = function (opts) {
        if (!('key' in opts)){
            opts.key = 'dataSourceKey' + (this._dataSource.length + 1);
        }

        var ajaxSetting = $.extend({} , this.ajaxOptsDefault , opts);

        this._dataSource.push({
            ajaxOpts: ajaxSetting,//jquery.ajax方法的参数
            ready: false,//数据是否已经加载
            data: null,//ajax加载的数据
            isFail : false,//数据是否加载失败
            successArguments: undefined,//jquery.ajax()方法，传入参数中的success回调函数的参数
            errorArguments: undefined,//jquery.ajax()方法，传入参数中的error回调函数的参数
            completeArguments : undefined//jquery.ajax()方法，传入参数中的complete回调函数的参数
        });
    };

    /**
     * 数据是否已经全部准备完毕
     * 如果dataSource中的所有ajax查询都完成了，则表示数据准备完毕
     * @returns {boolean}
     */
    DataReady.prototype._isReady = function () {
        var isReady = true;
        $.each(this._dataSource, function (key,value) {
            if (value.ready !== true) {
                isReady = false;
            }
        });
        return isReady;
    };

    /**
     * 每次ajax调用后，回调此方法。
     * 此方法判断是否所有数据都加载完毕，如果全部加载完毕，则逐个调用ajax的success,error,complete回调函数
     */
    DataReady.prototype._callReady = function () {
        if (this._isReady()) {
            $.each(this._dataSource, function (key,value) {
                var dataItem = value;
                if (!dataItem.isFail) {
                    typeof dataItem.ajaxOpts.success === 'function' ? dataItem.ajaxOpts.success(dataItem.successArguments) : '';
                }else{
                    typeof dataItem.ajaxOpts.error === 'function' ? dataItem.ajaxOpts.error(dataItem.errorArguments) : "";
                }
                typeof dataItem.ajaxOpts.complete === 'function' ? dataItem.ajaxOpts.complete(dataItem.completeArguments) : "";
            });
        }
    };


    /**
     * 启动dataReady
     * 要求pushDataSource方法中，设置的每个ajax的success,error,complete回调函数在所有数据加载完毕后全部回调一次
     */
    DataReady.prototype.start = function () {
        var self = this;

        var _initElement = function (key) {
            var dataItem = self._dataSource[key];
            var backSuccess = dataItem.ajaxOpts.success;
            dataItem.ajaxOpts.success = function () {
                dataItem.data = arguments[0];
                dataItem.successArguments = arguments;
                dataItem.ajaxOpts.success = backSuccess;
                self._callReady();
            };

            var backError = dataItem.ajaxOpts.error;
            dataItem.ajaxOpts.error = function () {
                self._dataSource[key].isFail = true;
                self._dataSource[key].errorArguments = arguments;
                dataItem.ajaxOpts.error = backError;
                self._callReady();
            };

            var backComplete = dataItem.ajaxOpts.complete;
            dataItem.ajaxOpts.complete = function () {
                self._dataSource[key].completeArguments = arguments;
                dataItem.ajaxOpts.complete = backComplete;
                dataItem.ready = true;
                self._callReady();
            };

            $.ajax(dataItem.ajaxOpts);
        };

        $.each(self._dataSource, function (key,value) {
            _initElement(key, value);
        });
        // for (var key in this._dataSource) {
        //     _initElement(key, this._dataSource[key]);
        // }
    };

    /**
     * 全部数据加载完毕后，回调一次ready方法
     * @param ready
     */
    DataReady.prototype._callOnce = function (ready) {
        if(ready != null &&ready != undefined && typeof ready === 'function' ){
            if (this._isReady()) {
                var data = {};
                $.each(this._dataSource , function(index , item){
                    data[item.ajaxOpts.key] = {
                        data : item.data,
                        isFail : item.isFail
                    }
                });
                ready(data);
            }
        }
    };

    /**
     * 启动dataReady
     * 在所有数据加载完毕后，回调一次ready方法。
     * pushDataSource方法中，设置的每个ajax的success,error,complete回调函数会被忽略，不会执行
     * @param ready = function(data){}
     * 其中，参数data的格式为:
     * data = {
     *  key1 : {data : {} , isFail : boolean}
     *  key2 : {data : {} , isFail : boolean}
     * }
     * key1、key2，是pushDataSource方法中，传入的参数中key属性定义的值
     * data，是本次数据执行结果
     * isFail ，如果ajax加载数据失败，则为true
     *
     */
    DataReady.prototype.once = function (ready_success,ready_error) {
        var self = this;

        var _initElement = function (key) {
            var dataItem = self._dataSource[key];
            dataItem.ajaxOpts.success = function () {
                dataItem.data = arguments[0];
                dataItem.ready = true;
                self._callOnce(ready_success);
            };

            dataItem.ajaxOpts.error = function () {

                self._dataSource[key].isFail = true;
                dataItem.ready = true;
                self._callOnce(ready_error);
            };

            $.ajax(dataItem.ajaxOpts);
        };

        $.each(self._dataSource, function (key,value) {
            _initElement(key, value);
        });
        // for (var key in this._dataSource) {
        //     // if (isNaN(parseInt(key))) return false;
        //     _initElement(key, this._dataSource[key]);
        // }
    };



    return DataReady;
});